from typing import Literal

from hhd.controller import Axis
from hhd.utils import hsb_to_rgb, rgb_to_hsb

DEFAULT_MAPPINGS: dict[str, tuple[Axis, str | None, float, float | None]] = {
    "accel_x": ("accel_z", "accel", 1, None),
    "accel_y": ("accel_x", "accel", -1, None),
    "accel_z": ("accel_y", "accel", -1, None),
    "anglvel_x": ("gyro_z", "anglvel", 1, None),
    "anglvel_y": ("gyro_x", "anglvel", -1, None),
    "anglvel_z": ("gyro_y", "anglvel", -1, None),
    "timestamp": ("imu_ts", None, 1, None),
}

AYA_DEFAULT_CONF = {
    "hrtimer": True,
    "mapping": DEFAULT_MAPPINGS,
}

CONFS = {
    # Ayaneo
    "AYANEO 3": {
        "name": "AYANEO 3",
        "extra_buttons": "quad",
        "magic_modules": True,
        "rgb": True,
        **AYA_DEFAULT_CONF,
    },
}

AYA3_INIT = [
    # Configure controller
    "0000000b07000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b07010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b07020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b07030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b07040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b07050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b07060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b07070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b07080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b07090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b070a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b070b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0068000b070c0000000000006800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0069000b070d0000000000006900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b070e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b070f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0070000b07100000000000007000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0071000b07110000000000007100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0011000b07120002000000000f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0017000b07130002000000001500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b07140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b07150000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0072000b07160000000000007200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0011000b07170002000008000700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "006b000b07180000000000006b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b07190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b071a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b071b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b071c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b071d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b071e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b071f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0000000b07200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
]


def pad(data: bytes | list[int], length: int = 65) -> bytes:
    return bytes(data).ljust(length, b"\x00")


def calculate_checksum_inplace(buf: bytes | list[int]):
    data = bytearray(buf)
    data[1:3] = sum(data[7:]).to_bytes(2, byteorder="little")
    return pad(data)


AYA_CHECK = pad([0x00, 0x00, 0x00, 0x00, 0x08])
AYA_CUSTOM = pad([0x00, 0x00, 0x00, 0x00, 0x0A, 0x02])
AYA_SAVE = pad([0x00, 0x00, 0x00, 0x00, 0x05])


def get_cfg_commands(
    rgb_mode: str,
    r,
    g,
    b,
    brightness: float,
    eject_left: bool = False,
    eject_right: bool = False,
    reset: bool = False,
    vibration: Literal["disabled", "low", "medium", "high"] = "medium",
):
    match rgb_mode:
        case "disabled":
            mode = 0xFF
        case "solid":
            mode = 1
        case "pulse":
            mode = 2
        case "rainbow":
            mode = 3
            # This has issues
            r, g, b = hsb_to_rgb(275, 100, min(int(brightness * 100), 100))
        case _:
            raise ValueError(f"Invalid RGB mode: {rgb_mode}")

    # Adjust hue slightly to color correct
    if rgb_mode in ["solid", "pulse"]:
        h, s, v = rgb_to_hsb(r, g, b)
        h = (h + 10) % 360
        r, g, b = hsb_to_rgb(h, s, v)

    ccmd = 0x00

    if reset:
        ccmd = 0x88
    if eject_left or eject_right:
        ccmd = (0x07 if eject_left else 0x00) + (0x70 if eject_right else 0x00)

    match vibration:
        case "low":
            c_vibration = 0x01
        case "medium":
            c_vibration = 0x02
        case "high":
            c_vibration = 0x03
        case _:  # "disabled":
            c_vibration = 0x04

    # Joystick sensitivity
    # 50-100-150% 1-3
    # Right, Left
    c_joysens = 0x22

    cmd = [
        # Report id
        0x00,
        # CRC
        0x00,
        0x00,
        # Command
        0x21,
        0x09,
        # Unknown
        0x00,
        0x00,
        0x00,
        # Right RGB, mode, color
        mode,
        r,
        g,
        b,
        # Left RGB, mode, color
        mode,
        r,
        g,
        b,
        # Uknown
        0x00,
        0x00,
        0x00,
        0x00,
        ccmd,
        0x00,
        0x33,
        c_joysens,
        c_vibration << 4,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x01,
        0x00,
        0x00,
        0x00,
        0x00,
        0x64,
        0x64,
    ]
    return [calculate_checksum_inplace(cmd)]
